/**
 * @description 深复制
 * @param source {Object} 复制对象
 * @returns {Object}
 */
export function deepClone (source) {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'shallowClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    for (const keys in source) {
        if (source.hasOwnProperty(keys)) {
            if (source[keys] && typeof source[keys] === 'object') {
                targetObj[keys] = source[keys].constructor === Array ? [] : {}
                targetObj[keys] = deepClone(source[keys])
            } else {
                targetObj[keys] = source[keys]
            }
        }
    }
    return targetObj
}
export function deepCppy(source, hash = new WeakMap()) {
    if (source == null || typeof source !== 'object') {
        return source;
    }

    if (source instanceof Date) {
        return new Date(source);
    }

    if (source instanceof RegExp) {
        return new RegExp(source);
    }

    // 如果循环引用了就用 weakMap 来解决
    if (hash.has(source)) return hash.get(source);

    let cloneTarget = Array.isArray(source) ? [] : {};
    hash.set(source, cloneTarget);

    for (let key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
            cloneTarget[key] = deepClone(source[key], hash);
        }
    }

    return cloneTarget;
}
// 生成uuid
export function getUuid () {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        let r = Math.random() * 16 | 0
        let v = c === 'x' ? r : (r & 0x3 | 0x8)
        return v.toString(16)
    })
}

export function smallToBig (money) { // 形参
    //  将数字金额转换为大写金额
    const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'] // 汉字的数字
    let cnIntRadice = ['', '拾', '佰', '仟'] // 基本单位
    let cnIntUnits = ['', '万', '亿', '兆'] // 对应整数部分扩展单位
    let cnDecUnits = ['角', '分', '毫', '厘'] // 对应小数部分单位
    let cnInteger = '整' // 整数金额时后面跟的字符
    let cnIntLast = '元' // 整数完以后的单位
    // 最大处理的数字
    let maxNum = 999999999999999.9999
    let integerNum // 金额整数部分
    let decimalNum // 金额小数部分
    // 输出的中文金额字符串
    let chineseStr = ''
    if (money === '') return ''
    money = parseFloat(money)
    if (money >= maxNum) {
        // 超出最大处理数字
        return '超出最大处理数字'
    }
    if (money === 0) {
        chineseStr = cnNums[0] + cnIntLast + cnInteger
        return chineseStr
    }

    // 四舍五入保留两位小数,转换为字符串
    money = Math.round(money * 100).toString()
    integerNum = money.substr(0, money.length - 2)
    decimalNum = money.substr(money.length - 2)

    // 获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
        let zeroCount = 0
        let IntLen = integerNum.length
        for (let i = 0; i < IntLen; i++) {
            let n = integerNum.substr(i, 1)
            let p = IntLen - i - 1
            let q = p / 4
            let m = p % 4
            if (n === '0') {
                zeroCount++
            } else {
                if (zeroCount > 0) {
                    chineseStr += cnNums[0]
                }
                // 归零
                zeroCount = 0
                chineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
            }
            if (m === 0 && zeroCount < 4) {
                chineseStr += cnIntUnits[q]
            }
        }
        chineseStr += cnIntLast
    }
    // 小数部分
    if (decimalNum !== '') {
        let decLen = decimalNum.length
        for (let i = 0; i < decLen; i++) {
            let n = decimalNum.substr(i, 1)
            if (n !== '0') {
                chineseStr += cnNums[Number(n)] + cnDecUnits[i]
            }
        }
    }
    if (chineseStr === '') {
        chineseStr += cnNums[0] + cnIntLast + cnInteger
    } else if (decimalNum === '' || /^0*$/.test(decimalNum)) {
        chineseStr += cnInteger
    }
    return chineseStr
}
